package cn.reone.mbt.ui;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelUuid;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.AppCompatEditText;
import android.support.v7.widget.AppCompatTextView;
import android.text.method.ScrollingMovementMethod;
import android.view.KeyEvent;
import android.view.inputmethod.EditorInfo;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.util.UUID;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import cn.reone.mbt.R;
import cn.reone.mbt.connect.ConnectedThread;

public class ClientActivity extends AppCompatActivity {
    public static final String BLUETOOTH_DEVICE = "bluetoothDevice";
    private final UUID MY_UUID = UUID.nameUUIDFromBytes("cn.reone.mbt".getBytes());
    @BindView(R.id.info_show)
    AppCompatTextView infoShow;
    @BindView(R.id.socket_show)
    AppCompatTextView socketShow;
    @BindView(R.id.socket_send)
    AppCompatEditText socketSend;

    private BluetoothAdapter mBluetoothAdapter;
    private BluetoothDevice mDevice;
    private ClientThread mClientThread;
    private BluetoothSocket mSocket;
    private ConnectedThread mConnectedThread;
    private BluetoothDevice remoteDevice;
    private StringBuffer msgInfo = new StringBuffer();
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == ConnectedThread.MESSAGE_READ) {
                if (msg.what == ConnectedThread.MESSAGE_READ) {
                    if (msg.obj!=null && msg.obj instanceof byte[]) {
                        msgInfo.append("\nmsg: " + new String((byte[]) msg.obj));
                    }
                    socketShow.setText(msgInfo);
                }
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_client);
        ButterKnife.bind(this);
        mDevice = getIntent().getParcelableExtra(BLUETOOTH_DEVICE);
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        updateDeviceInfo();
        socketShow.setMovementMethod(ScrollingMovementMethod.getInstance());
        socketSend.setImeOptions(EditorInfo.IME_ACTION_SEND);
        socketSend.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                mConnectedThread.write(socketSend.getText().toString().getBytes());
                socketSend.setText("");
                socketSend.clearFocus();
                return false;
            }
        });
    }

    public void talk(final String str) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(ClientActivity.this, str, Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void updateDeviceInfo() {
        if (mDevice == null) return;
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                StringBuffer sb = new StringBuffer();
                sb.append("name: " + mDevice.getName());
                sb.append("\naddress: " + mDevice.getAddress());
                sb.append("\nstate: " + mDevice.getBondState());
                if (remoteDevice != null) {
                    sb.append("\nremote : " + remoteDevice.getName() + "\n->" + remoteDevice.getAddress());
                }
                infoShow.setText(sb.toString());
            }
        });
    }

    @OnClick(R.id.create_client)
    public void createSocket() {
        mClientThread = new ClientThread(mDevice);
        mClientThread.start();
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mClientThread != null) {
            mClientThread.cancel();
        }
        if (mConnectedThread != null) {
            mConnectedThread.cancel();
        }
    }

    class ClientThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;

        public ClientThread(BluetoothDevice device) {
            // Use a temporary object that is later assigned to mmSocket,
            // because mmSocket is final
            BluetoothSocket tmp = null;
            mmDevice = device;

            // Get a BluetoothSocket to connect with the given BluetoothDevice
            try {
                // MY_UUID is the app's UUID string, also used by the server code
                tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
            } catch (IOException e) {
            }
            mmSocket = tmp;
        }

        public void run() {
            mBluetoothAdapter.cancelDiscovery();
            try {
                talk("开始建立连接");
                mmSocket.connect();
                remoteDevice = mmSocket.getRemoteDevice();
                updateDeviceInfo();
                talk("已建立连接: " + remoteDevice.getAddress());
            } catch (IOException connectException) {
                try {
                    mmSocket.close();
                } catch (IOException closeException) {
                }
                return;
            }
            manageConnectedSocket(mmSocket);
        }

        /**
         * Will cancel an in-progress connection, and close the socket
         */
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
            }
        }
    }

    /**
     * 用来处理线程中获取到的socket,此socket可以用来数据传输
     *
     * @param mmSocket
     */
    private void manageConnectedSocket(BluetoothSocket mmSocket) {
        mSocket = mmSocket;
        mConnectedThread = new ConnectedThread(mSocket, mHandler);
        mConnectedThread.start();
        mConnectedThread.write("hello,here is client".getBytes());
    }
}
